package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleConfigMapper;
import com.heima.article.mapper.ApArticleContentMapper;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.FreemarkerService;
import com.heima.common.exception.CustomException;
import com.heima.common.redis.CacheService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.dtos.ArticleInfoDto;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.vos.ArticleCommentVo;
import com.heima.model.comment.dtos.CommentNewsQueryDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.dtos.StatisticsDto;
import com.heima.model.wemedia.vos.StatisticsVo;
import com.heima.utils.thread.AppThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author jack
 * @data 2024 11:30
 */
@Service
@Transactional
@Slf4j
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {

    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private ApArticleConfigMapper apArticleConfigMapper;
    @Autowired
    private ApArticleContentMapper apArticleContentMapper;
    @Autowired
    private FreemarkerService freemarkerService;
    @Autowired
    private CacheService cacheService;

    /**
     * app热点文章加载
     *
     * @param homeDto 筛选条件
     * @param type    控制开关：1 表示加载首页和加载更多  2:表示加载更新
     * @return
     */
    @Override
    public ResponseResult load1(ArticleHomeDto homeDto, int type) {
        //先查redis获取热点文章
        String hotArticleAll = null;
        if(homeDto.getTag().equals("__all__")){
            hotArticleAll = cacheService.get("hot_article__all__");
        }else {
            hotArticleAll = cacheService.get("hot_article_"+homeDto.getTag());
        }
        if(hotArticleAll!=null){
            List<ApArticle> apArticleList = JSON.parseArray(hotArticleAll, ApArticle.class);
            return ResponseResult.okResult(apArticleList);
        }
        //redis拿不到，再去数据库拿
        return load(homeDto,type);
    }

    /**
     * app文章加载
     *
     * @param homeDto 筛选条件
     * @param type    控制开关：1 表示加载首页和加载更多  2:表示加载更新
     * @return
     */
    @Override
    public ResponseResult load(ArticleHomeDto homeDto, int type) {


        List<ApArticle> list = apArticleMapper.load(homeDto, type);
        return ResponseResult.okResult(list);
    }

    /**
     * 同步自媒体文章到app端
     *
     * @param articleDto
     * @return
     */
    @Override
    public ResponseResult saveOrUpdateArticle(ArticleDto articleDto) {
        ApArticle article = new ApArticle();
        BeanUtils.copyProperties(articleDto, article);

        //1. 判断有没有id
        if (articleDto.getId() == null) {
            //没有：就新增   -- ap_article, ap_article_config, ap_article_content
            apArticleMapper.insert(article);
            articleDto.setId(article.getId());

            ApArticleConfig config = new ApArticleConfig(article.getId());
            apArticleConfigMapper.insert(config);

            ApArticleContent content = new ApArticleContent();
            content.setContent(articleDto.getContent());
            content.setArticleId(article.getId());
            apArticleContentMapper.insert(content);

        } else {
            //有：就修改     -- ap_article, ap_article_content
            apArticleMapper.updateById(article);

            ApArticleContent content = apArticleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery()
                    .eq(ApArticleContent::getArticleId, articleDto.getId()));
            content.setContent(articleDto.getContent());
            apArticleContentMapper.updateById(content);
        }

        //生成文章的详情页
        freemarkerService.buildPage(articleDto);

        //2. 将文章id返回给调用者
        return ResponseResult.okResult(String.valueOf(article.getId()));
    }

    /**
     * 文章上下架
     *
     * @param map
     */
    @Override
    public void downOrUpArticle(Map map) {
        //先拿到文章id和enable的值
        String articleId = map.get("articleId").toString();
        Short enable = Short.valueOf(map.get("enable").toString());

        boolean isDown = false;      //默认上架
        if (enable == 0) {
            isDown = true;
        }

        ApArticleConfig config = new ApArticleConfig();
        config.setArticleId(Long.valueOf(articleId));
        config.setIsDown(isDown);
        apArticleConfigMapper.update(config, Wrappers.<ApArticleConfig>lambdaUpdate()
                .set(ApArticleConfig::getIsDown, isDown)
                .eq(ApArticleConfig::getArticleId, articleId));

    }

    /**
     * @param dto :
     * @return ResponseResult<?>
     * @author 18297
     * @date 2024/1/26 14:57
     * @description 加载文章行为数据回显
     */
    @Override
    public ResponseResult<?> loadArticleBehavior(ArticleInfoDto dto) {
        // 校验参数
        if (dto.getArticleId() == null || dto.getAuthorId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 获取登录的用户的id
        Integer id = AppThreadLocalUtil.getUser().getId();
        // 收集行为数据
        boolean isCollection = false;
        //是否收藏
        String collction = (String) cacheService.hGet("collection_" + id, dto.getArticleId().toString());
        if (StringUtils.isNotBlank(collction)) {
            isCollection = true;
        }
        boolean isLike = false;
        String islike = (String) cacheService.hGet("like_" + dto.getArticleId().toString(), id.toString());
        if (StringUtils.isNotBlank(islike)) {
            isLike = true;
        }
        boolean isUnlike = false;
        String isunlike = (String) cacheService.hGet("unlike_" + dto.getArticleId().toString(), id.toString());
        if (StringUtils.isNotBlank(isunlike)) {
            isUnlike = true;
        }
        boolean isFollow = false;
        String isfollw = (String) cacheService.hGet("isFollow_" + id, dto.getAuthorId().toString());
        if (StringUtils.isNotBlank(isfollw)) {
            isFollow = true;
        }

        // 封装结果数据返回
        Map<String, Object> map = new HashMap<>();
        map.put("iscollection", isCollection);
        map.put("islike", isLike);
        map.put("isunlike", isUnlike);
        map.put("isfollow", isFollow);
        return ResponseResult.okResult(map);
    }

    @Override
    public void addCommentCount(Map map) {
        //拿到
        String articleId = map.get("articleId").toString();
        //查找文章
        ApArticle apArticle = getOne(Wrappers.<ApArticle>lambdaQuery().eq(ApArticle::getId, articleId));
        ApArticle apArticleQuery = new ApArticle();
        apArticleQuery.setId(Long.valueOf(articleId));
        if (apArticle.getComment() == null) {
            //第一次添加评论
            apArticleQuery.setComment(1);
        } else {
            //不是第一次评论，将评论数加1
            apArticleQuery.setComment(apArticle.getComment() + 1);
        }
        //评论数更新
        apArticleMapper.updateById(apArticleQuery);
    }

    /**
     * 功能描述：分页条件查询文章评论
     *
     * @param dto
     * @return {@link ResponseResult }
     * @author sungang
     * @date 2024/01/27  14:39
     */

    @Override
    public PageResponseResult findnewsQueryComents(CommentNewsQueryDto dto) {
        //参数校验
        if (dto == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();
        //参数处理
        Integer currentPage = dto.getPage();
        Integer pageSize = dto.getSize();
        Integer pageQuery = (currentPage - 1) * pageSize;
        dto.setPage(pageQuery);
        List<ArticleCommentVo> list = apArticleMapper.findnewsQueryComents(dto);
        int count = apArticleMapper.findnewsQueryComentsCount(dto);

        PageResponseResult result = new PageResponseResult(currentPage, pageSize, count);
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), list, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    @Override
    public PageResponseResult newPage(StatisticsDto dto) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = new Date();
        Date endDate = new Date();
        try {
            beginDate = sdf.parse(dto.getBeginDate());
            endDate = sdf.parse(dto.getEndDate());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // page,size检查
        dto.checkParam();
        Page<ApArticle> page = new Page<>(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<ApArticle> lambdaQueryWrapper = Wrappers.<ApArticle>lambdaQuery()
                .eq(ApArticle::getAuthorId, dto.getWmUserId())
                .between(ApArticle::getPublishTime, beginDate, endDate)
                .select(ApArticle::getId, ApArticle::getTitle, ApArticle::getLikes, ApArticle::getCollection, ApArticle::getComment, ApArticle::getViews);

        lambdaQueryWrapper.orderByDesc(ApArticle::getPublishTime);
        page = page(page, lambdaQueryWrapper);
        List<ApArticle> records = page.getRecords();
        List<StatisticsVo> voList = records.stream().map(item -> {
            StatisticsVo statisticsVo = new StatisticsVo();
            statisticsVo.setTitle(item.getTitle());
            statisticsVo.setCollection(item.getCollection() == null ? 0 : item.getCollection());
            statisticsVo.setLikes(item.getLikes() == null ? 0 : item.getLikes());
            statisticsVo.setViews(item.getViews() == null ? 0 : item.getViews());
            statisticsVo.setComment(item.getComment() == null ? 0 : item.getComment());
            return statisticsVo;
        }).collect(Collectors.toList());
        PageResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        responseResult.setData(voList);

        return responseResult;
    }

    /**
     * @param wmUserId  :
     * @param beginDate :
     * @param endDate   :
     * @return ResponseResult
     * @author 18297
     * @date 2024/1/28 19:19
     * @description 文章数据统计
     */
    @Override
    public ResponseResult countAllDate(Integer wmUserId, Date beginDate, Date endDate) {
        Map map = apArticleMapper.countAllDate(wmUserId, beginDate, endDate);
        return ResponseResult.okResult(map);
    }

}
